package com.fingard.dsp.bank.directbank.cwgs01;

import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2019/4/25.
 */
public class CWGS01SinglePay extends CWGS01Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        return p_req1908.singleDetail.sameBnk.equals("1")?
                payBetweenSameBanks(p_req1908):
                payBetweenDiffBnaks(p_req1908);

    }

    private RetAtsSingle payBetweenDiffBnaks(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        String valied ="";
        RetAtsSglDetail detail = new RetAtsSglDetail();
            try {
                valied =login(p_req1908.reqHeader.transType);
                XmlTextWriter xmlWriter =  new XmlTextWriter();
                CWGS01Header header = new CWGS01Header();
                header.batchNo = p_req1908.reqHeader.transSeqID;
                header.bizCode ="8200";
                wirteCommenHeader(xmlWriter,header);
                XElement body = new XElement("BODY","");
//                ERP端付款唯一标识	ERP_INS_ID	C32		所有的付款业务类型统一标识
                body.addChild(new XElement("ERP_INS_ID",p_req1908.singleDetail.askNumber));
//                付款方ID	PAYER_ID	C18	Y	财务公司系统付款方单位编号x;
                String payerId = getBankConfig().getMapValueByKey("UnitNo",p_req1908.singleDetail.payAct);
                body.addChild(new XElement("PAYER_ID",payerId));
//                付款方内部账号	PAYER_NO	C32	Y	财务公司系统内的内部结算账号（若使用结算账户付款，不能为空，否则可以为空）
                body.addChild(new XElement("PAYER_NO",p_req1908.singleDetail.payAct));
//                付款方银行账号	PAYBANK_NO	C32	Y	财务公司系统内的银行账号（若使用银行账号付款，不能为空，否则可以为空）
                body.addChild(new XElement("PAYBANK_NO",""));
//                预算号	BUDGET_NO	C60		必填 财务公司预算项目编号
                String budget_no = getBudgetNo(p_req1908.singleDetail.payAct,p_req1908.singleDetail.budgetItemCode,valied);
                if(StringHelper.isNullOrEmpty(budget_no)){
                    throw new Exception("找不到对应的预算编号！");
                }
                body.addChild(new XElement("BUDGET_NO",budget_no));
//                付款日期	PAY_DATE	D		期望付款日，格式：YYYY-MM-DD
                body.addChild(new XElement("PAY_DATE", Format.Date10Format.format(new Date())));
//                摘要	ABSTRACT	C60
                body.addChild(new XElement("ABSTRACT",p_req1908.singleDetail.purpose));
//                结算方式	TR_TYPE	C2		网银转账T
                body.addChild(new XElement("TR_TYPE","T"));
//                付款金额	AMOUNT	N15.2
                body.addChild(new XElement("AMOUNT",p_req1908.singleDetail.payAmount));
//                币种	CURRENCY	C3		人民币CNY
                body.addChild(new XElement("CURRENCY",convertCurToBank(p_req1908.singleDetail.payCur)));
//                收款方账号	RECE_ACC_NO	C32
                body.addChild(new XElement("RECE_ACC_NO",p_req1908.singleDetail.recAct));
//                收款方户名	RECE_ACC_NAME	C60
                body.addChild(new XElement("RECE_ACC_NAME",p_req1908.singleDetail.recName));
//                收款方标准地名编码	REG_NO	C4		财务公司系统内标准地址编码
                body.addChild(new XElement("REG_NO",p_req1908.singleDetail.recArea));
//                收款方开户行	RECE_OPBANK_NO	C60		开户行大行名称（和财务公司系统内名称一致）
                body.addChild(new XElement("RECE_OPBANK_NO",p_req1908.singleDetail.cnapsCode));
//                收款方开户行名称	RECE_OPBANK_NAME	C60		具体开户的支行
                body.addChild(new XElement("RECE_OPBANK_NAME",p_req1908.singleDetail.cnapsName));
//                收款方开户行CNAPS号	RECE_CNAPS	C12	Y	大额联行号
                body.addChild(new XElement("RECE_CNAPS",p_req1908.singleDetail.cnapsCode));
//                加急标识	URGENT_FLAG	C2		加急Y,不加急N
                body.addChild(new XElement("URGENT_FLAG","1".equals(p_req1908.singleDetail.paySpd)?"Y":"N"));
//                对私标记	PERSONALFLAG	C2	Y	默认对公；对公‘1’、对私‘2’
                body.addChild(new XElement("PERSONALFLAG","1".equals(p_req1908.singleDetail.isPrivate)?"2":"1"));
//                录入人	CREATOR	C20	Y	录入人姓名
                body.addChild(new XElement("CREATOR",""));
//                录入时间	CREATE_TIME	D	Y	YYYY-MM-DD
                body.addChild(new XElement("CREATE_TIME",""));
//                文本备用字段1	TEXTVALUE1	C255	Y
                body.addChild(new XElement("TEXTVALUE1",""));
//                文本备用字段2	TEXTVALUE2	C255	Y
                body.addChild(new XElement("TEXTVALUE2",""));
//                文本备用字段3	TEXTVALUE3	C255	Y
                body.addChild(new XElement("TEXTVALUE3",""));
//                文本备用字段4	TEXTVALUE4	C255	Y
                body.addChild(new XElement("TEXTVALUE4",""));
//                文本备用字段5	TEXTVALUE5	C255	Y
                body.addChild(new XElement("TEXTVALUE5",""));
//                数字备用字段1	NUMBERVALUE1	N	Y
                body.addChild(new XElement("NUMBERVALUE1",""));
//                数字备用字段2	NUMBERVALUE2	N15.2	Y
                body.addChild(new XElement("NUMBERVALUE2",""));
//                数字备用字段3	NUMBERVALUE3	N15.2	Y
                body.addChild(new XElement("NUMBERVALUE3",""));
//                时间备用字段1	DATEVALUE1	D	Y
                body.addChild(new XElement("DATEVALUE1",""));
//                时间备用字段2	DATEVALUE2	D	Y
                body.addChild(new XElement("DATEVALUE2",""));
//                时间备用字段3	DATEVALUE3	D	Y
                body.addChild(new XElement("DATEVALUE3",""));
//                用户名	USERNAME	C32		用户名
                body.addChild(new XElement("USERNAME",bankFront.loginName));
//                验证码	VALIDATE_CODE	C32		验证码
                body.addChild(new XElement("VALIDATE_CODE",valied));
                nodeAnalysis(p_req1908.singleDetail.srcXElement,body,getCharset());
                xmlWriter.writeXElement(body);
                xmlWriter.writeEndDocument();
                String[] bankResult = sendToBank(xmlWriter.toXmlString());
                if (bankResult[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                        String retCode = tmpBkReader.getFirstText("/XERP/BODY/RET_CODE");
                        String retMsg = tmpBkReader.getFirstText("/XERP/BODY/RET_MSG");
                        detail.respCode = "0";
                        detail.respInfo = retMsg;
                        detail.transState = retCode;
                        detail.payInfoCode = retCode;
                        detail.reqSeqID = p_req1908.singleDetail.askNumber;
                }else if (bankResult[0].equals(ConnState.FAIL)) {
                    detail.respCode = "0";
                    detail.respInfo = bankResult[1];
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                    detail.transState = PaymentState.FAIL_Payment;
                    detail.payInfoCode = bankResult[0];
                } else {
                    throw new Exception(bankResult[1]);
                }
            }catch (Exception ex){
                ex.printStackTrace();
                detail.respCode = "-1";
                detail.respInfo = ex.getMessage();
           }finally {
                logout(valied,p_req1908.reqHeader.transType);
            }
           retAts.writeRetDetail(detail);
        return retAts;
    }

    private RetAtsSingle payBetweenSameBanks(ReqSingle p_req1908)throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        String valied ="";
        RetAtsSglDetail detail = new RetAtsSglDetail();
        try {
            valied =login(p_req1908.reqHeader.transType);
            XmlTextWriter xmlWriter =  new XmlTextWriter();
            CWGS01Header header = new CWGS01Header();
            header.batchNo = p_req1908.reqHeader.transSeqID;
            header.bizCode ="8201";
            wirteCommenHeader(xmlWriter,header);
            XElement body = new XElement("BODY","");
//                ERP端付款唯一标识	ERP_INS_ID	C32		所有的付款业务类型统一标识
            body.addChild(new XElement("ERP_INS_ID",p_req1908.singleDetail.askNumber));
//                付款方ID	PAYER_ID	C18	Y	财务公司系统付款方单位编号x;
            String payerId = getBankConfig().getMapValueByKey("UnitNo",p_req1908.singleDetail.payAct);
            body.addChild(new XElement("PAYER_ID",payerId));
//                付款方内部账号	PAYER_ACNT_NO	C32	Y	财务公司系统内的内部结算账号（若使用结算账户付款，不能为空，否则可以为空）
            body.addChild(new XElement("PAYER_ACNT_NO",p_req1908.singleDetail.payAct));
//                预算号	BUDGET_NO	C60		必填 财务公司预算项目编号
            if(StringHelper.isNullOrEmpty(p_req1908.singleDetail.budgetItemCode)){
                body.addChild(new XElement("BUDGET_NO",""));
            }else{
                String budget_no = getBudgetNo(p_req1908.singleDetail.payAct,p_req1908.singleDetail.budgetItemCode,valied);
                body.addChild(new XElement("BUDGET_NO",budget_no));
            }

//                付款日期	PAY_DATE	D		期望付款日，格式：YYYY-MM-DD
            body.addChild(new XElement("PAY_DATE", Format.Date10Format.format(new Date())));
//                摘要	ABSTRACT	C60
            body.addChild(new XElement("ABSTRACT",p_req1908.singleDetail.purpose));
          //                付款金额	AMOUNT	N15.2
            body.addChild(new XElement("AMOUNT",p_req1908.singleDetail.payAmount));
//                币种	CURRENCY	C3		人民币CNY
            body.addChild(new XElement("CURRENCY",convertCurToBank(p_req1908.singleDetail.payCur)));
//            收款方ID	RECE_ID	C18	Y	财务公司系统收款方唯一标识
            body.addChild(new XElement("RECE_ID",""));
//            收款方内部账号	RECE_ACNT_NO	C32
            body.addChild(new XElement("RECE_ACNT_NO",p_req1908.singleDetail.recAct));
            //            收款方户名   RECE_ACNT_NAME
            body.addChild(new XElement("RECE_ACNT_NAME",p_req1908.singleDetail.recName));
//            录入人	CREATOR	C20		录入人姓名
            body.addChild(new XElement("CREATOR",p_req1908.singleDetail.payName));
//                录入时间	CREATE_TIME	D	Y	YYYY-MM-DD
            body.addChild(new XElement("CREATE_TIME",Format.Date10Format.format(new Date())));
//                文本备用字段1	TEXTVALUE1	C255	Y
            body.addChild(new XElement("TEXTVALUE1",""));
//                文本备用字段2	TEXTVALUE2	C255	Y
            body.addChild(new XElement("TEXTVALUE2",""));
//                文本备用字段3	TEXTVALUE3	C255	Y
            body.addChild(new XElement("TEXTVALUE3",""));
//                文本备用字段4	TEXTVALUE4	C255	Y
            body.addChild(new XElement("TEXTVALUE4",""));
//                文本备用字段5	TEXTVALUE5	C255	Y
            body.addChild(new XElement("TEXTVALUE5",""));
//                数字备用字段1	NUMBERVALUE1	N	Y
            body.addChild(new XElement("NUMBERVALUE1",""));
//                数字备用字段2	NUMBERVALUE2	N15.2	Y
            body.addChild(new XElement("NUMBERVALUE2",""));
//                数字备用字段3	NUMBERVALUE3	N15.2	Y
            body.addChild(new XElement("NUMBERVALUE3",""));
//                时间备用字段1	DATEVALUE1	D	Y
            body.addChild(new XElement("DATEVALUE1",""));
//                时间备用字段2	DATEVALUE2	D	Y
            body.addChild(new XElement("DATEVALUE2",""));
//                时间备用字段3	DATEVALUE3	D	Y
            body.addChild(new XElement("DATEVALUE3",""));
//                用户名	USERNAME	C32		用户名
            body.addChild(new XElement("USERNAME",bankFront.loginName));
//                验证码	VALIDATE_CODE	C32		验证码
            body.addChild(new XElement("VALIDATE_CODE",valied));
            nodeAnalysis(p_req1908.singleDetail.srcXElement,body,getCharset());
            xmlWriter.writeXElement(body);
            xmlWriter.writeEndDocument();
            String[] bankResult = sendToBank(xmlWriter.toXmlString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                    String retCode = tmpBkReader.getFirstText("/XERP/BODY/RET_CODE");
                    String retMsg = tmpBkReader.getFirstText("/XERP/BODY/RET_MSG");
                    detail.respCode = "0";
                    detail.respInfo = retMsg;
                    detail.transState = retCode;
                    detail.payInfoCode = retCode;
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
            } else if (bankResult[0].equals(ConnState.FAIL)) {
                detail.respCode = "0";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                detail.transState = PaymentState.FAIL_Payment;
                detail.payInfoCode = bankResult[0];
            }else {
                throw new Exception(bankResult[1]);
            }
        }catch (Exception ex){
            ex.printStackTrace();
            detail.respCode = "-1";
            detail.respInfo = ex.getMessage();
        }finally {
            logout(valied,p_req1908.reqHeader.transType);
        }
        retAts.writeRetDetail(detail);
        return retAts;
    }

    private String getBudgetNo(String actnum,String bcode,String valied)throws Exception{
        String buggetNo ="";
        try {
            XmlTextWriter xmlWriter =  new XmlTextWriter();
            CWGS01Header header = new CWGS01Header();
            header.batchNo = getQryTransID("6002");
            header.bizCode ="6002";
            wirteCommenHeader(xmlWriter,header);
            xmlWriter.writeStartElement("BODY");
//            账户	ACNT_NO	C32		　
            xmlWriter.writeElementString("ACNT_NO",actnum );
//            期望付款日期	MIDDLE_DATE	D
            xmlWriter.writeElementString("MIDDLE_DATE",Format.Date8Format.format(new Date()) );
//            预算项目编号	BCODE	C18	Y	模糊匹配
            xmlWriter.writeElementString("BCODE", bcode);
//            用户名	USERNAME	C32		用户名
            xmlWriter.writeElementString("USERNAME",bankFront.loginName );
//            验证码	VALIDATE_CODE	C32		验证码
            xmlWriter.writeElementString("VALIDATE_CODE", valied);
            xmlWriter.writeEndDocument();
            String[] bankResult = sendToBank(xmlWriter.toXmlString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                String retCode = tmpBkReader.getFirstText("/XERP/BODY/RET_CODE");
                String retMsg = tmpBkReader.getFirstText("/XERP/BODY/RET_MSG");
                String rowNum = tmpBkReader.getFirstText("/XERP/BODY/ROW_NUM");
                if ("0".equals(retCode)) {
                    if (StringHelper.isNullOrEmpty(rowNum)) {
                        throw new Exception("根据预算项目编号【" + bcode + "】查不到对应的预算编号，请核查！");
                    }
                    while (tmpBkReader.read("/XERP/BODY/DETAIL/ROW")){
                        String code =tmpBkReader.readedXElement.getSingleText("BCODE");
                        if(bcode.equals(code)) {
                             buggetNo = tmpBkReader.readedXElement.getSingleText("BUDGET_NO");
                            break;
                        }
                    }
                } else {
                    throw new Exception(bankResult[1]);
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
            throw  ex;
        }
        return buggetNo;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        String valied ="";
        try {
            valied =login(p_req1944.reqHeader.transType);
            XmlTextWriter xmlWriter =  new XmlTextWriter();
            CWGS01Header header = new CWGS01Header();
            header.batchNo = p_req1944.reqHeader.transSeqID;
            header.bizCode ="8300";
            wirteCommenHeader(xmlWriter,header);
            xmlWriter.writeStartElement("BODY");
//            ERP端付款唯一标识	ERP_INS_ID	C32		所有的付款业务类型统一标识
            xmlWriter.writeElementString("ERP_INS_ID",p_req1944.askNumber);
//            用户名	USERNAME	C32		用户名
            xmlWriter.writeElementString("USERNAME", bankFront.loginName);
//            验证码	VALIDATE_CODE	C32		验证码
            xmlWriter.writeElementString("VALIDATE_CODE",valied );
            xmlWriter.writeEndDocument();
            String[] bankResult = sendToBank(xmlWriter.toXmlString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);

                    String retCode = tmpBkReader.getFirstText("/XERP/BODY/RET_CODE");
                    String retMsg = tmpBkReader.getFirstText("/XERP/BODY/RET_MSG");
                    detail.respCode = "0";
                    detail.respInfo = retMsg;
                    detail.transState = retCode;
                    detail.payInfoCode = retCode;
                    detail.reqSeqID = tmpBkReader.getFirstText("/XERP/BODY/INS_ID");

            } else {
                throw new Exception(bankResult[1]);
            }
        }catch (Exception ex){
            ex.printStackTrace();
            detail.respCode = "-1";
            detail.respInfo = ex.getMessage();
        }finally {
            logout(valied,p_req1944.reqHeader.transType);
        }
        retAts.writeRetDetail(detail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
